<template>
  <div class="net-debug">
    <el-card class="page-header" shadow="never">
      <h2>网络调试工具</h2>
      <p>支持TCP/UDP通信调试和数据监控</p>
    </el-card>

    <div class="debug-container">
      <!-- 网络配置区域 -->
      <el-card class="config-panel" shadow="hover">
        <template #header>
          <div class="card-header">
            <span>网络配置</span>
            <el-button-group>
              <el-button type="primary" @click="connect" :disabled="isConnected">连接</el-button>
              <el-button @click="disconnect" :disabled="!isConnected">断开</el-button>
            </el-button-group>
          </div>
        </template>

        <el-form :model="netConfig" label-width="100px">
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="连接模式">
                <el-select v-model="netConfig.mode" placeholder="请选择连接模式" :disabled="isConnected">
                  <el-option label="客户端模式" value="client"></el-option>
                  <el-option label="服务端模式" value="server"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="协议类型">
                <el-select v-model="netConfig.protocol" placeholder="请选择协议类型" :disabled="isConnected">
                  <el-option label="TCP" value="tcp"></el-option>
                  <el-option label="UDP" value="udp"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item :label="netConfig.mode === 'client' ? '主机地址' : '监听地址'">
                <el-input v-model="netConfig.host" :placeholder="netConfig.mode === 'client' ? '请输入主机地址' : '请输入监听地址'" :disabled="isConnected" /></el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="端口">
                <el-input v-model.number="netConfig.port" type="number" placeholder="请输入端口号" min="1" max="65535" :disabled="isConnected" /></el-form-item>
            </el-col>
          </el-row>

          <el-form-item label="连接状态">
            <el-tag :type="isConnected ? 'success' : 'info'">
              {{ isConnected ? '已连接' : '未连接' }}
            </el-tag>
            <span v-if="isConnected" style="margin-left: 10px; color: #909399;">
              {{ connectionInfo?.localAddress }}:{{ connectionInfo?.localPort }}
            </span>
          </el-form-item>

          <!-- 连接信息 -->
          <div class="connection-info" v-if="connectionInfo">
            <h4>连接信息</h4>
            <el-row :gutter="10">
              <el-col :span="12">
                <p><strong>连接ID:</strong> {{ connectionInfo.connectionId }}</p>
              </el-col>
              <el-col :span="12">
                <p><strong>状态:</strong> <span :class="['status', isConnected ? 'connected' : 'disconnected']">{{ isConnected ? '已连接' : '已断开' }}</span></p>
              </el-col>
              <el-col :span="12">
                <p v-if="connectionInfo.remoteAddress"><strong>远程地址:</strong> {{ connectionInfo.remoteAddress }}</p>
              </el-col>
              <el-col :span="12">
                <p v-if="connectionInfo.remotePort"><strong>远程端口:</strong> {{ connectionInfo.remotePort }}</p>
              </el-col>
              <el-col :span="12">
                <p v-if="connectionInfo.localAddress"><strong>本地地址:</strong> {{ connectionInfo.localAddress }}</p>
              </el-col>
              <el-col :span="12">
                <p v-if="connectionInfo.localPort"><strong>本地端口:</strong> {{ connectionInfo.localPort }}</p>
              </el-col>
            </el-row>
          </div>
        </el-form>
      </el-card>

      <!-- 数据收发区域 -->
      <el-row :gutter="20" class="data-panels">
        <!-- 发送区域 -->
        <el-col :span="12">
          <el-card shadow="hover">
            <template #header>
              <div class="card-header">
                <span>数据发送</span>
                <el-button type="primary" @click="send" :disabled="!isConnected">
                  发送
                </el-button>
              </div>
            </template>

            <el-form>
              <el-form-item label="发送格式">
                <el-radio-group v-model="sendFormat">
                  <el-radio label="text">文本</el-radio>
                  <el-radio label="hex">十六进制</el-radio>
                </el-radio-group>
              </el-form-item>
              <el-form-item>
                <el-input
                  v-model="sendData"
                  type="textarea"
                  placeholder="请输入要发送的数据"
                  :rows="15"
                  :disabled="!isConnected"
                ></el-input>
              </el-form-item>

              <el-form-item>
                <el-button @click="clearSendData" :disabled="!isConnected">清空</el-button>
              </el-form-item>
            </el-form>
          </el-card>
        </el-col>

        <!-- 接收区域 -->
        <el-col :span="12">
          <el-card shadow="hover">
            <template #header>
              <div class="card-header">
                <span>数据接收</span>
                <el-button @click="clearData">清空</el-button>
              </div>
            </template>

            <el-form>
              <el-form-item label="显示格式">
                <el-radio-group v-model="receiveFormat">
                  <el-radio label="text">文本</el-radio>
                  <el-radio label="hex">十六进制</el-radio>
                </el-radio-group>
              </el-form-item>

              <el-form-item>
                <el-input
                  v-model="receiveData"
                  type="textarea"
                  placeholder="接收的数据将显示在这里"
                  :rows="15"
                  readonly
                ></el-input>
              </el-form-item>
              
              <!-- 占位元素，保持与发送区域高度一致 -->
              <el-form-item label="">
                <div style="height: 32px;"></div>
              </el-form-item>
            </el-form>
          </el-card>
        </el-col>
      </el-row>

      <!-- 统计信息 -->
      <el-card shadow="hover" class="stats-panel">
        <template #header>
          <span>通信统计</span>
        </template>
        <el-row :gutter="20">
          <el-col :span="4">
            <el-statistic title="发送字节数" :value="connectionInfo?.stats?.bytesSent || 0" />
          </el-col>
          <el-col :span="4">
            <el-statistic title="接收字节数" :value="connectionInfo?.stats?.bytesReceived || 0" />
          </el-col>
          <el-col :span="4">
            <el-statistic title="发送数据包数" :value="connectionInfo?.stats?.packetsSent || 0" />
          </el-col>
          <el-col :span="4">
            <el-statistic title="接收数据包数" :value="connectionInfo?.stats?.packetsReceived || 0" />
          </el-col>
        </el-row>
      </el-card>
    </div>
  </div>
</template>

<script>
import { netApi } from '../api/index.js'

export default {
  name: 'NetDebug',
  data() {
    return {
      // 网络配置
    netConfig: {
      mode: 'client', // client 或 server
      protocol: 'tcp', // tcp 或 udp
      host: 'localhost',
      port: 8080
    },
    
    // 为不同模式保存默认host值
    defaultHosts: {
      client: 'localhost',
      server: '0.0.0.0'
    },
      
      // 连接状态
      isConnected: false,
      connectionInfo: null,
      webSocket: null,
      // 断开提示标志，避免重复弹窗
      disconnectAlertShown: false,
      
      // 数据发送和接收
      sendData: '',
      receiveData: '',
      sendFormat: 'text',
      receiveFormat: 'text'
    }
  },
  
  // 监听模式变化
  watch: {
    'netConfig.mode'(newMode, oldMode) {
      if (newMode !== oldMode && !this.isConnected) {
        // 切换模式且未连接时，更新host为对应模式的默认值
        this.netConfig.host = this.defaultHosts[newMode]
      }
    },
    
    // 监听接收格式变化，重新格式化现有数据
    'receiveFormat'() {
      if (this.receiveData) {
        // 保存当前数据
        const currentData = this.receiveData
        // 清空接收区域
        this.clearData()
        
        // 重新处理每一行数据（保留时间戳）
        const lines = currentData.split('\n')
        for (const line of lines) {
          if (line && line.includes(']')) {
            // 提取时间戳和数据部分
            const parts = line.split('] ')
            if (parts.length >= 2) {
              const timestamp = parts[0] + ']'
              const data = parts.slice(1).join('] ')
              
              // 格式化数据
              const formattedData = this.formatDataForDisplay(data, this.receiveFormat)
              // 重新添加到接收区域
              this.receiveData += `${timestamp} ${formattedData}\n`
            }
          }
        }
      }
      this.$message.info('显示格式已切换，已重新格式化现有数据')
    }
  },
  
  beforeUnmount() {
    // 组件卸载时断开连接
    this.disconnect()
  },
  
  methods: {    
    // 连接网络
    async connect() {
        try {
          this.isConnected = false
          const response = await netApi.connect(this.netConfig)
          // 适配后端返回的数据格式，确保connectionId字段存在
          const connectionData = response.data
          if (connectionData.connection_id && !connectionData.connectionId) {
            connectionData.connectionId = connectionData.connection_id
          }
          this.connectionInfo = connectionData
          this.isConnected = true
          
          // 连接WebSocket获取实时数据
          this.connectWebSocket()
          
          this.$message.success('连接成功')
        } catch (error) {
          this.$message.error(`连接失败: ${error.message}`)
          console.error('连接失败:', error)
        }
      },
    
    // 断开网络连接
    async disconnect() {
      if (!this.isConnected || !this.connectionInfo?.connectionId) {
        return
      }
      
      try {
        // 先关闭WebSocket连接
        if (this.webSocket) {
          this.webSocket.close()
          this.webSocket = null
        }
        
        // 再断开HTTP连接
        await netApi.disconnect(this.connectionInfo.connectionId)
        this.isConnected = false
        this.connectionInfo = null
        // 重置断开提示标志，因为这是用户主动断开的
        this.disconnectAlertShown = false
        
        this.$message.success('断开连接成功')
      } catch (error) {
        this.$message.error(`断开连接失败: ${error.message}`)
        console.error('断开连接失败:', error)
      }
    },
    
    // 连接WebSocket获取实时数据
    connectWebSocket() {
      if (!this.connectionInfo?.connectionId) {
        console.error('连接失败：缺少有效的connectionId')
        this.$message.error('连接失败：缺少有效的连接ID')
        return
      }
      
      // 添加调试日志
      console.log('正在创建WebSocket连接:', {
        connectionId: this.connectionInfo.connectionId,
        connectionInfo: this.connectionInfo
      })
      
      // 关闭已存在的WebSocket连接
      if (this.webSocket) {
        this.webSocket.close()
      }
      
      try {
        // 创建新的WebSocket连接
        this.webSocket = netApi.createWebSocket(
          this.connectionInfo.connectionId,
          this.onWebSocketMessage,
          this.onWebSocketClose,
          this.onWebSocketError
        )
      } catch (error) {
        console.error('创建WebSocket连接时发生异常:', error)
        this.$message.error(`创建WebSocket连接失败: ${error.message}`)
      }
    },
    
    // WebSocket消息处理
    onWebSocketMessage(message) {
      console.log('收到消息:', message)
      
      if (message.type === 'data') {
        // 显示接收到的数据
        // 根据后端返回的格式，使用message.data或message.text
        this.appendReceiveData(message.data || message.text)
      } else if (message.type === 'heartbeat' || message.type === 'status') {
        // 处理心跳消息和状态消息
        if (message.data) {
          const wasConnected = this.isConnected
          this.connectionInfo = message.data
          this.isConnected = message.data.status === 'connected'
          
          // 连接恢复时重置断开提示标志
          if (this.isConnected) {
            this.disconnectAlertShown = false
          }
          // 只有从连接状态变为断开状态且未显示过提示时，才显示断开提示
          else if (wasConnected && !this.disconnectAlertShown) {
            this.onWebSocketClose()
            this.showDisconnectAlert()
          }
        }
      } else if (message.type === 'error') {
        // 处理错误消息
        this.$message.error(`WebSocket错误: ${message.message}`)
        console.error('WebSocket错误:', message.message)
      }
    },
    
    // WebSocket关闭处理
    onWebSocketClose() {
      this.webSocket = null
      // 如果当前是连接状态，更新为断开状态并显示提示
      if (this.isConnected && !this.disconnectAlertShown) {
        this.isConnected = false
        this.showDisconnectAlert()
      }
    },
    
    // 显示断开连接提示（确保只显示一次）
    showDisconnectAlert() {
      if (!this.disconnectAlertShown) {
        this.disconnectAlertShown = true
        this.$message.warning('连接已断开')
      }
    },
    
    // WebSocket错误处理
    onWebSocketError(error) {
      const errorDetails = error ? error.message || JSON.stringify(error) : '未知错误'
      console.error('WebSocket错误:', error)
      this.$message.error(`WebSocket连接发生错误: ${errorDetails}`)
    },
    
    // 发送数据
    async send() {
      if (!this.isConnected || !this.connectionInfo?.connectionId || !this.sendData.trim()) {
        this.$message.error('发送数据失败')
        return
      }
      
      try {
        // 先保存原始发送数据和格式
        const originalSendData = this.sendData
        const originalSendFormat = this.sendFormat
        
        // 发送数据
        await netApi.sendData(this.connectionInfo.connectionId, originalSendData, originalSendFormat)
        
        // 在接收区域显示发送的数据（带方向标记）
        // 如果发送格式和接收格式不同，需要进行格式转换
        let displayData = originalSendData
        if (originalSendFormat === 'hex' && this.receiveFormat === 'text') {
          // 十六进制转文本
          try {
            const hexBytes = originalSendData.split(' ')
            let text = ''
            for (const hex of hexBytes) {
              if (hex.trim()) {
                const charCode = parseInt(hex.trim(), 16)
                if (!isNaN(charCode)) {
                  text += String.fromCharCode(charCode)
                }
              }
            }
            displayData = text
          } catch (e) {
            console.error('发送数据十六进制转文本失败:', e)
            // 转换失败，使用原始数据
          }
        } else if (originalSendFormat === 'text' && this.receiveFormat === 'hex') {
          // 文本转十六进制
          let hex = ''
          for (let i = 0; i < originalSendData.length; i++) {
            hex += originalSendData.charCodeAt(i).toString(16).padStart(2, '0') + ' '
          }
          displayData = hex.trim()
        }
        
        this.appendReceiveData(`TX: ${displayData}`)
      } catch (error) {
        this.$message.error(`发送失败: ${error.message}`)
        console.error('发送失败:', error)
      }
    },
    
    // 追加接收数据
    appendReceiveData(data) {
      // 获取当前时间并格式化
      const now = new Date()
      const timestamp = now.toLocaleString('zh-CN', {
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        hour12: false
      })
      
      // 移除数据末尾的换行符，避免重复添加
      const cleanData = data.endsWith('\n') ? data.slice(0, -1) : data
      
      // 格式化数据显示
      const formattedData = this.formatDataForDisplay(cleanData, this.receiveFormat)
      
      // 追加到接收区域（带时间戳）
      this.receiveData += `[${timestamp}] ${formattedData}\n`
      
      // 滚动到底部
      this.$nextTick(() => {
        const textarea = this.$el.querySelector('textarea[readonly]')
        if (textarea) {
          textarea.scrollTop = textarea.scrollHeight
        }
      })
    },
    
    // 格式化数据显示
    formatDataForDisplay(data, format) {
      if (typeof data !== 'string') {
        return data
      }
      
      if (format === 'hex') {
        // 检查数据是否已经是十六进制格式（如果包含多个空格分隔的两位字符，可能已经是十六进制）
        const hexMatch = data.match(/^([0-9a-fA-F]{2} )+[0-9a-fA-F]{2}$/)
        if (!hexMatch) {
          // 文本转十六进制显示
          let hex = ''
          for (let i = 0; i < data.length; i++) {
            hex += data.charCodeAt(i).toString(16).padStart(2, '0') + ' '
          }
          return hex.trim()
        }
        return data // 已经是十六进制格式，直接返回
      } else {
        // 文本格式：检查数据是否是十六进制格式，如果是则转换为文本
        const hexMatch = data.match(/^([0-9a-fA-F]{2} )+[0-9a-fA-F]{2}$/)
        if (hexMatch) {
          // 十六进制转文本
          try {
            const hexBytes = data.split(' ')
            let text = ''
            for (const hex of hexBytes) {
              const charCode = parseInt(hex, 16)
              if (!isNaN(charCode)) {
                text += String.fromCharCode(charCode)
              }
            }
            return text
          } catch (e) {
            console.error('十六进制转文本失败:', e)
            return data // 转换失败，返回原始数据
          }
        }
        return data // 不是十六进制格式，直接返回
      }
    },
    
    // 清空接收数据
    clearData() {
      this.receiveData = ''
    },
    
    // 清空发送数据
    clearSendData() {
      this.sendData = ''
    }
  }
}
</script>

<style scoped>
.net-debug {
  padding: 20px;
  height: 100vh;
  overflow-y: auto;
}

.page-header {
  margin-bottom: 20px;
  border: none;
}

.page-header h2 {
  margin: 0 0 10px 0;
  color: #303133;
}

.page-header p {
  margin: 0;
  color: #909399;
}

.debug-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.config-panel {
  border: none;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.data-panels {
  margin: 0;
}

.stats-panel {
  border: none;
}

.el-card {
  border-radius: 8px;
}

.el-statistic {
  text-align: center;
}

.connection-info {
  margin-top: 20px;
  padding: 10px;
  background-color: #f8f9fa;
  border-radius: 4px;
}

.connection-info h4 {
  margin-top: 0;
  margin-bottom: 10px;
  font-size: 14px;
}

.connection-info p {
  margin: 5px 0;
  font-size: 12px;
}

.status {
  padding: 2px 8px;
  border-radius: 3px;
  font-size: 12px;
  color: white;
}

.status.connected {
  background-color: #28a745;
}

.status.disconnected {
  background-color: #dc3545;
}
</style>